/*this module is code by erek 2009-3-19*/
#include "zdfl_parameter_define.h"
#include "dv_OSD.h"
#include "md_OSD.h"
#include "Printf.h"

#include "gui_icon_data.c"
#include "gui_scratch_data.c"
#include "gui_font_data.c"
#include "gui_canvas_data.c"
#include "gui_palette_data.c"

U8 OSDLang=0;
#ifdef Used_BlockTransfer
extern U8 BlockTransStatus;
#endif

#ifdef Update_AvoidBlink
extern U8 UpdateStatus;
#endif

#ifdef Support_PagerSlide
U8 PagerSlideStatus=0;
U8 PagerSlideDirection=0;
#endif

void MD_OSDLayer_Init(void)
{
	OSD_Layer_Init();
}

void MD_WaitOSDBlank(U8 Cnt)
{
	OSD_WaitOSDBlank(Cnt);
}

void MD_WaitDisplayBlank(U8 Cnt)
{
	OSD_WaitDisplayBlank(Cnt);
}
#ifdef Used_BlockTransfer 
void MD_BlockTransfer(U16 sx, U16 sy, U16 w, U16 h, U16 dx, U16 dy,U8 DispMode)
{
	OSD_BlockTransfer(sx,sy,w,h,dx,dy,DispMode);
}
#endif

/******************************************************************************
 Control the Canvas On or Off
 
Parameters
CanNO is canvas's number
OnOff is a static symbol which indicate the canvas whether on or off
*******************************************************************************/
void MD_Win_OnOff(U8 CanNO, U8 OnOff )
{
	CANVAS* pCanvas;
	U8 WinNO;
	U8 i,blink_level;

	pCanvas = &User_Canvas[CanNO];
	WinNO=pCanvas->Display_Layer;
	
	//OSD_SetBlinkEnable(0);
	
	//Canvas Attribute
	for(i=0;i<4;i++)
	{
		if(pCanvas->attribute[i].attri_kind==0xff) break;

		//Canvas Attribute, here is blink
		if(pCanvas->attribute[i].attri_kind==0x02)
		{
			blink_level=pCanvas->attribute[i].Level;
			OSD_BlinkIntervalSetting(blink_level);
		}
	}
	//Printf("\n CanNO:%bd\r\n",CanNO);
	//Printf("\n WinNO:%bd\r\n",WinNO);
	OSD_ShowWindowBmp(WinNO,OnOff);
	//Printf("\n OnOff:%bd\r\n",OnOff);
}

void MD_SetWin_GlobalAlpha(U8 winno,U8 level)
{
	OSD_GlobalWindowAlpha(winno, level);
}

void MD_SetWin_PerPixelAlpha(U8 winno)
{
	OSD_PerPixelAlpha(winno);
}

void MD_SetWin_ColorKeyAlpha(U8 colorNum,U16 *color, U8 level)
{
	OSD_ColorKeyAlpha(colorNum,color, level);
}

void MD_SetAlphaBlending_Disable(U8 WinNO)
{
	OSD_AttrAlpha_Disable(WinNO);
}

void MD_SetWin_MemoryPosition(U8 WinNO,U16 xp,U16 yp)
{
	OSD_SetWindowMemoryPosition(WinNO, xp, yp);
}

void MD_SetWin_Infomation(U8 WinNO,U16 HStart,U16 HLength,U16 VStart,U16 VLength)
{
	OSD_SetWindowInfo(WinNO, HStart,HLength, VStart, VLength);
}

void MD_SetCtrl_ConvertColor(U8 colorNum,U16 *cvColor, U8 DispMode)
{
	OSD_ConvertColor(colorNum,cvColor,DispMode);
}

void MD_SetCtrl_OverWriteColor(U8 colorNum,U16 *cvColor, U8 DispMode)
{
	OSD_OverWriteColor(colorNum,cvColor,DispMode);
}

void MD_SetColorConvert_Disable(void)
{
	SetColorConvertDisable();
}

void MD_SetSelectiveOvWrite_Disable(void)
{
	SetSelectiveOvWriteDisable();
}

/******************************************************************************
Get the current active user defined Palette number, which is the position inside the PALETTE
structure array of User_Palette[], for specific Hardware palette.
Parameters:
HW_PaletteID used to specify hardware palette.
*******************************************************************************/
static char MD_Get_SW_Palette_ID(U8 HW_PaletteID)
{
	return System_Palette[HW_PaletteID];
}


/******************************************************************************
Save the current active user defined Palette number, which is the position inside the PALETTE
structure array of User_Palette[], for specific Hardware palette.
Parameters:
HW_PaletteID used to specify hardware palette.
SW_PaletteID is a soft palette which is used just now
*******************************************************************************/
static void MD_Update_Palette_Map(U8 HW_PaletteID, U8 SW_PaletteID)
{
	System_Palette[HW_PaletteID] = SW_PaletteID;
}

/******************************************************************************
   Load selected palette to HW "iPaletteID" corresponsed table
   pPalette         pointer to Palette table
   iPaletteID       Indicate which HW palette need be loaded.
                    	   0 is windows0
 			   1 is windows1	

*******************************************************************************/
static void MD_Osd_Load_Palette( U8 iPaletteID, PALETTE * pPalette)
{
	U8 BitMode=0;
	U8 N=pPalette->pal_entries_number;

	if(N==255)
		BitMode=8;
	else if(N==16)
		BitMode=4;
	else if(N==4)
		BitMode=2;
	else if(N==2)
		BitMode=1;
	
	if(BitMode==8||BitMode==4||BitMode==2||BitMode==1)
	OSD_LoadLUT(iPaletteID,BitMode,(const U8 *)(pPalette->palette_entry));


}

/******************************************************************************
 Set window Pallette
 
Parameters
canvas_id is canvas's number
pal_id is pallette number which will be use by canvas
*******************************************************************************/
void MD_Win_Pallette_Set(U8 canvas_id, U8 pal_id)
{
	CANVAS* pCanvas;
	U8 Palette_Used;
	
	pCanvas = &User_Canvas[canvas_id];

	if(pCanvas->Display_Layer==0||pCanvas->Display_Layer==1)  //win4 not use look up table
	{
		Palette_Used = MD_Get_SW_Palette_ID(pCanvas->HW_Palette_ID);
		//Printf("\ncanvas_id:%bx\r\n",canvas_id);
		//Printf("\pal_id:%bx\r\n",pal_id);
		//Printf("\Palette_Used:%bx\r\n",Palette_Used);
	
		//judge whether need to load palette again
		//if(Palette_Used != pal_id) //del for Jason's Demo 20100413
		{

			PALETTE * pPalette	= &User_Palette[pal_id];
			//OSD_WaitEndofDisplayArea();
			
			MD_Osd_Load_Palette(pCanvas->HW_Palette_ID, pPalette);
			MD_Update_Palette_Map(pCanvas->HW_Palette_ID, pal_id);
		}
	}
}

/*********************************************************
Using to write the bitmap to the display buffer or scratch buffer.

Parameters:
Destination_Index can be the user canvas' index or scratch page index. If "Destination_Type" is the
"DISPLAY_BUFFER", it will be the canvas position inside CANVAS type array of User_Canvas[ ]. If
"Destination_Type" is the "SCRATCH_BUFFER", it will be the scratch page position inside SCRATCH
type array of User_Scratch_Page[ ].

Destination_Type can either be DISPLAY_BUFFER or SCRATCH_BUFFER.

pCntr using to control the attribute of the bitmap, include the alpha, blinking, zoom etc and specific
the memory address, it's address is a relatived address.

pBMP point to a bitmap structure which need be written to the display memory or scratch memory.
**********************************************************/
static void MD_BMP_Write(U8 Destination_Index, U8 Destination_Type, IconControl_struct *pCntr,  BITMAP * pBMP)
{
	U16 X, Y;
	U8 DispMode;

	X=pCntr->XY1.X;
	Y=pCntr->XY1.Y;

	#ifndef DP80390
	if(Destination_Type == SCRATCH_BUFFER)
	{
		X=X+User_Scratch_Page[Destination_Index].Address1;			
   		Y=Y+User_Scratch_Page[Destination_Index].Address2;
		if(User_Scratch_Page[Destination_Index].TargetPlane_Bits_Per_Pixel==8)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
	}
	else
	#endif
	{
		X = X + User_Canvas[Destination_Index].Mem_X;
		Y = Y + User_Canvas[Destination_Index].Mem_Y;
		if(User_Canvas[Destination_Index].Display_Layer==0||User_Canvas[Destination_Index].Display_Layer==1)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
/*
		#ifdef Used_BlockTransfer
		if((BlockTransStatus==1)&&(DispMode==0x10))
			X=X+800;
		#endif

		//Printf("\r\n X=%d",X);
		//Printf("\r\n BlockTransStatus=%bd",BlockTransStatus);
		//Printf("\r\n DispMode=%bx",DispMode);

		#ifdef Update_AvoidBlink
		if((UpdateStatus==1)&&(DispMode==0x10))
			X=X+800;
		//Printf("\nmdBmp_X=%d\r\n",X);
		#endif

		#ifdef Support_PagerSlide
		if((PagerSlideStatus==1)&&(DispMode==0x10))
		{
			if(PagerSlideDirection==0x02) //direction is left
			X=X+800;
			else if(PagerSlideDirection==0x03) //direction is right
			X=X+0;
			else if(PagerSlideDirection==0x00) //direction is up
			Y=Y+480;
			else if(PagerSlideDirection==0x01) //direction is down
			Y=Y+0;
		}
		#endif
*/
		Y += 272;
	}

	//Printf("\n pBMP->bmpdata:%lx\r\n",pBMP->bmpdata);
	//Printf("\n pBMP->data_length:%lx\r\n",pBMP->data_length);

	OSD_LoadBmp((const U8 *)pBMP, X, Y, DispMode);	
}

/******************************************************************************
Display the Bitmap, here exist two ways that one is from Scracth buffer to Display buffer, another is 
from flash to Display buffer. It is judged by array SystemIconStore[].
location>=2 means stored in scratch memory, and the location -2 is the scratch page number
QuickIndex is the scratch item number inside the scratch page, when location>=2.

Parameters:
UIIcon provide Canvas_ID which bitmap will be display on and BMP_ID which will be display.
*******************************************************************************/
void MD_BMP_Display(UIControlIcon_struct * UIIcon)
{
	CANVAS* pCanvas;
	U16 icon_index;
	POINT* pos;
	U8 Palette_Used,DispMode;
	BITMAP* pBMP;

	icon_index = UIIcon->BMP_ID;
	pos = &(UIIcon->DispControl->XY1);

	pCanvas = &User_Canvas[UIIcon->Canvas_ID];

	pBMP= &SystemIcon[icon_index];
	/*
	Palette_Used = TWLL_Get_SW_Palette_ID(pCanvas->HW_Palette_ID);
	//judge whether need to load palette again
	if(Palette_Used != pBMP->palette_id)
		{
			CONST PALETTE * pPalette	= &User_Palette[pBMP->palette_id];
			
			TWLL_Osd_Load_Palette(pCanvas->HW_Palette_ID, pPalette);
			TWLL_Update_Palette_Map(pCanvas->HW_Palette_ID, pBMP->palette_id);

		}*/

	//Printf("\nerek");
	#ifndef DP80390
	if(SystemIconStore[SystemIcon[icon_index].Store_Array_Index].location<2)
	{
		MD_BMP_Write(UIIcon->Canvas_ID, DISPLAY_BUFFER, UIIcon->DispControl, pBMP);
	}
	else
	{
		U16 StartX,StartY,DestX,DestY,Width,Heigh;
		SCRATCH * pScratch;
		SCRATCH_CONTENT *Content_table;

		U8 location = SystemIconStore[SystemIcon[icon_index].Store_Array_Index].location - 2;

	 	pScratch = &(User_Scratch_Page[location]);
		DispMode=pScratch->TargetPlane_Bits_Per_Pixel;
		Content_table= pScratch->Content_table + SystemIconStore[SystemIcon[icon_index].Store_Array_Index].QuickIndex;

		StartX = Content_table->Start_x+pScratch->Address1;
		StartY = Content_table->Start_y+pScratch->Address2;

		DestX= pos->X+pCanvas->Mem_X;
		DestY = pos->Y+pCanvas->Mem_Y;

		Width = SystemIcon[icon_index].width;
		Heigh = SystemIcon[icon_index].height;

		#ifdef Used_BlockTransfer
		if((BlockTransStatus==1)&&(DispMode==16))
			DestX=DestX+800;
		#endif

		#ifdef Update_AvoidBlink
		if((UpdateStatus==1)&&(DispMode==0x10))
			DestX=DestX+800;
		#endif

		#ifdef Support_PagerSlide
		if((PagerSlideStatus==1)&&(DispMode==0x10))
		{
			if(PagerSlideDirection==0x02) //direction is left
			DestX=DestX+800;
			else if(PagerSlideDirection==0x03) //direction is right
			DestX=DestX+0;
			else if(PagerSlideDirection==0x00) //direction is up
			DestY=DestY+480;
			else if(PagerSlideDirection==0x01) //direction is down
			DestY=DestY+0;
		}
		#endif
		
		OSD_BlockTransfer(StartX, StartY, Width, Heigh, DestX, DestY,DispMode);
		
	}
	#else
	MD_BMP_Write(UIIcon->Canvas_ID, DISPLAY_BUFFER, UIIcon->DispControl, pBMP);
	#endif
}


/******************************************************************************
Using to write the bitmap to the scratch buffer.

Parameters:
SW_scratch_page_index point out which scratch pager will be written.
Content_table provide the position that will be located on which part of scratch pager, it a relatived address
Content_table.Type indicates whether this item is a icon (0) or font set (1). Font set is a group of font.
Content_table.Index indicates the icon position inside BITMAP type array SystemIcon[ ], if Type=0; or font set
position inside the FONTINFO type array System_Font[ ]
*******************************************************************************/
#ifndef DP80390
static void MD_BMP_To_Scratch(U8 SW_scratch_page_index, SCRATCH_CONTENT *Content_table)
{
	BITMAP *pBMP = &SystemIcon[Content_table->Index] ;
	IconControl_struct Cntr;
 
	Cntr.XY1.X = Content_table->Start_x;
	Cntr.XY1.Y = Content_table->Start_y;

	MD_BMP_Write(SW_scratch_page_index, SCRATCH_BUFFER, &Cntr, pBMP);
}
#endif

/*********************************************************
Using to write the Font to the display buffer or scratch buffer.

Parameters:
Destination_Index can be the user canvas' index or scratch page index. If "Destination_Type" is the
"DISPLAY_BUFFER", it will be the canvas position inside CANVAS type array of User_Canvas[ ]. If
"Destination_Type" is the "SCRATCH_BUFFER", it will be the scratch page position inside SCRATCH
type array of User_Scratch_Page[ ].

Destination_Type can either be DISPLAY_BUFFER or SCRATCH_BUFFER.

FCntr using to control the attribute of the Font, include the alpha, blinking, zoom etc and specific
the memory address, it's address is a relatived address.

FontInfo point to the Font Set information structure, which used control how to write font to the
display memory or scratch memory.

Font_NumIndex indicate the index inside the specific font set. (note: This index is not the Unicode)
**********************************************************/
static void MD_Font_Write(U8 Destination_Index, U8 Destination_Type, FontControl_struct *FCntr,  FONTINFO * FontInfo, U16 Font_NumIndex)
{
    	U16 X, Y;
	U8 DispMode;

	X=FCntr->XY1.X;
	Y=FCntr->XY1.Y;

	#ifndef DP80390
	if(Destination_Type == SCRATCH_BUFFER)
	{
		X=X+User_Scratch_Page[Destination_Index].Address1;			
   		Y=Y+User_Scratch_Page[Destination_Index].Address2;
		if(User_Scratch_Page[Destination_Index].TargetPlane_Bits_Per_Pixel==8)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
	}
	else
	#endif
	{
		X=X+User_Canvas[Destination_Index].Mem_X;
		Y=Y+User_Canvas[Destination_Index].Mem_Y;
		if(User_Canvas[Destination_Index].Display_Layer==0||User_Canvas[Destination_Index].Display_Layer==1)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4

		#ifdef Used_BlockTransfer
		if((BlockTransStatus==1)&&(DispMode==0x10))
			X=X+800;
		#endif

		#ifdef Update_AvoidBlink
		if((UpdateStatus==1)&&(DispMode==0x10))
			X=X+800;
		//Printf("\nmdfont_X=%d\r\n",X);
		#endif

		#ifdef Support_PagerSlide
		if((PagerSlideStatus==1)&&(DispMode==0x10))
		{
			if(PagerSlideDirection==0x02) //direction is left
			X=X+800;
			else if(PagerSlideDirection==0x03) //direction is right
			X=X+0;
			else if(PagerSlideDirection==0x00) //direction is up
			Y=Y+480;
			else if(PagerSlideDirection==0x01) //direction is down
			Y=Y+0;
		}
		#endif
	}				

	OSD_LoadFont((const U8 *)FontInfo,X,Y,DispMode,Font_NumIndex);	
		
}


/******************************************************************************
Display the Font, here exist two ways that one is from Scracth buffer to Display buffer, another is 
from flash to Display buffer. It is judged by array System_FontStore[].
location>=2 means stored in scratch memory, and the location -2 is the scratch page number
QuickIndex is the scratch item number inside the scratch page, when location>=2.

Parameters:
Canvas_ID is that bitmap will be display on.

FCntr using to control the attribute of the FOnt, include the alpha, blinking, zoom etc and specific
the memory address, it's address is a relatived address.

Font_index is a character's Unicode, which indicate which font information to get.
*******************************************************************************/
void MD_FONT_Display(U8 CanvasID, FontControl_struct *FCntr, U16 Font_index)
{
	unsigned char i;
	CANVAS* pCanvas = &User_Canvas[CanvasID];

	for(i=0;i<MAX_FONT_SET;i++)
	{
		if((System_Font_Index[i].first_character <= Font_index) && (System_Font_Index[i].last_character >= Font_index))break;
	}

	#ifdef DEBUG
		if(i == MAX_FONT_SET) Printf("\r\nThe Font Set not existing\n");
	#endif

	Font_index -= System_Font_Index[i].first_character; //gain font number

	#ifndef DP80390
	if(System_FontStore[System_Font[i].Store_Array_Index].location<2)
	{
		MD_Font_Write(CanvasID, DISPLAY_BUFFER, FCntr,  &System_Font[i], Font_index);
	}
	else
	{
		U16 StartX,StartY,DestX,DestY,Width,Heigh;
		SCRATCH * pScratch; 
		SCRATCH_CONTENT *Content_table;
		U8 Font_W,Font_MaxW,DispMode;
		U16 Numb_X,Numb_Y;
		
		U8 location = System_FontStore[System_Font[i].Store_Array_Index].location-2;

		pScratch = &(User_Scratch_Page[location]);
		DispMode=pScratch->TargetPlane_Bits_Per_Pixel;
		Content_table = pScratch->Content_table + System_FontStore[System_Font[i].Store_Array_Index].QuickIndex;

		Font_W = (System_Font[i].character_info + Font_index)->character_width;

		DestX = FCntr->XY1.X+pCanvas->Mem_X;
		DestY = FCntr->XY1.Y+pCanvas->Mem_Y;

		switch(System_Font[i].bits_per_pixel)
		{
			case 1:
				Font_W = (Font_W+7)>>3<<3;
				break;
			case 2:
				Font_W = (Font_W+3)>>2<<2;
				break;
			case 4:
				Font_W = (Font_W+1)>>1<<1;
				break;
		}

		Width=Font_W;
		Heigh=(System_Font[i].character_info + Font_index)->character_height;
		
		Font_MaxW = System_Font[i].max_character_width;

		//ensure Source_startx is multiplys of 16
		Font_MaxW=(Font_MaxW>>4<<4)+16;

		//serch the source start_x and start_y
		Numb_X=(pScratch->Scratch_Memory_width-Content_table->Start_x)/Font_MaxW;
		Numb_Y=Font_index/Numb_X;

		StartX = pScratch->Address1+Content_table->Start_x+ (Font_index%Numb_X)*Font_MaxW;
		StartY = pScratch->Address2+Content_table->Start_y+Numb_Y*(System_Font[i].max_character_height);

		#ifdef Used_BlockTransfer
		if((BlockTransStatus==1)&&(DispMode==16))
			DestX=DestX+800;
		#endif

		#ifdef Update_AvoidBlink
		if((UpdateStatus==1)&&(DispMode==0x10))
			DestX=DestX+800;
		#endif

		#ifdef Support_PagerSlide
		if((PagerSlideStatus==1)&&(DispMode==0x10))
		{
			if(PagerSlideDirection==0x02) //direction is left
			DestX=DestX+800;
			else if(PagerSlideDirection==0x03) //direction is right
			DestX=DestX+0;
			else if(PagerSlideDirection==0x00) //direction is up
			DestY=DestY+480;
			else if(PagerSlideDirection==0x01) //direction is down
			DestY=DestY+0;
		}
		#endif

		OSD_BlockTransfer(StartX, StartY, Width, Heigh, DestX, DestY,DispMode);
		
	}
	#else
	MD_Font_Write(CanvasID, DISPLAY_BUFFER, FCntr,  &System_Font[i], Font_index);
	#endif

}

/******************************************************************************
Display the string by calling TWLL_FONT_Display().

Parameters:
Struct UIString provide Canvas_ID which string will be display on, display location, direction etc
Direction=0 means show string from the left to right, XY1 will be the left top point of the string
Direction=1 means show string from the right to left, XY1 will be the right top point of the string
Direction =2 means show string from the top to bottom, XY1 will be the left top point of the string
Direction =3 means show string from the bottom to top, XY1 will be the left bottom of the string
*******************************************************************************/
void MD_String_Display(UIControlString_struct * UIString)
{

	unsigned char i,Font_W, Font_H;
	U16 *str;
	//U8 back_color, front_color;
	FontControl_struct tmpcnt;

	tmpcnt.XY1.X     = UIString->DispControl->XY1.X;
	tmpcnt.XY1.Y     = UIString->DispControl->XY1.Y;

	str = UIString->Character[OSDLang].Str_Lang;

	while(*str)
	{
		MD_FONT_Display(UIString->Canvas_ID, &tmpcnt, *str);
		MD_Get_FONT_Size(*str,&Font_W, &Font_H);
		str++;
		
		switch(UIString->Direction)
		{	
			case 0:				
				tmpcnt.XY1.X = tmpcnt.XY1.X+Font_W+UIString->SpaceBetweenCharacter;
				break;
			case 1:
				tmpcnt.XY1.X = tmpcnt.XY1.X-Font_W-UIString->SpaceBetweenCharacter;
				break;
			case 2:
				tmpcnt.XY1.Y = tmpcnt.XY1.Y+Font_H+UIString->SpaceBetweenCharacter;
				break;
			case 3:
				tmpcnt.XY1.Y = tmpcnt.XY1.Y-Font_H-UIString->SpaceBetweenCharacter;
				break;
		}
	}


}



/******************************************************************************
Using to write the Font to the scratch buffer.

Parameters:
SW_scratch_page_index point out which scratch pager will be written.
Content_table provide the first font position that will be located on which part of scratch pager, it a relatived address,
and other font position is decided by adding to character's width.
Content_table.Type indicates whether this item is a icon (0) or font set (1). Font set is a group of font.
Content_table.Index indicates the icon position inside BITMAP type array SystemIcon[ ], if Type=0; or font set
position inside the FONTINFO type array System_Font[ ]
*******************************************************************************/
#ifndef DP80390
static void MD_FONT_to_Scratch(U8 SW_scratch_page_index, SCRATCH_CONTENT *Content_table)
{
	unsigned char Font_MaxW, Font_MaxH;
	U16 i, Length;
	SCRATCH * pScratch = &(User_Scratch_Page[SW_scratch_page_index]);
	FONTINFO * FontInfo= &System_Font[Content_table->Index];

	FontControl_struct tmpcnt;

	tmpcnt.XY1.X     = Content_table->Start_x; 
	tmpcnt.XY1.Y     = Content_table->Start_y; 


	Length = FontInfo->last_character - FontInfo->first_character + 1;
	Font_MaxH= FontInfo->max_character_height;
	Font_MaxW = FontInfo->max_character_width;

	//ensure Source_startx is multiplys of 16
	Font_MaxW=(Font_MaxW>>4<<4)+16;

	for(i=0;i<Length; i++) //write struct FONTINFO content, including many characters
	{
		//change the line, and ensure not to exceed borderline of Scratch. 
		if((tmpcnt.XY1.X+Font_MaxW) >pScratch->Scratch_Memory_width)
		{
			tmpcnt.XY1.X = Content_table->Start_x;
			tmpcnt.XY1.Y += Font_MaxH;
		}
		MD_Font_Write(SW_scratch_page_index, SCRATCH_BUFFER, &tmpcnt, FontInfo, i);
	
		//because write font to SDRAM with 8 bits saving, font occupying SDRAM is equal to pixel' number
		//target is that decide the next charcter's start location 
		tmpcnt.XY1.X += Font_MaxW;
		
	}
}
#endif

/******************************************************************************
 Load the scratch page content into the memory
 
Parameters
SW_scratch_page_index is the scratch page position inside the SCRATCH type array
User_Scratch_Page[ ].   
*******************************************************************************/
#ifndef DP80390
void MD_Load_Scratch_page( U8 user_scratch_page_id)
{

	SCRATCH * pScratch = &User_Scratch_Page[user_scratch_page_id];
	SCRATCH_CONTENT *Content_table;
	U8 i;

	for(i=0;i<pScratch->Conten_Table_Item_Number;i++)
	{
		Content_table = pScratch ->Content_table+i; //equal to Content_table = &(pScratch ->Content_table[i]);

		if(Content_table->Type == ICON_TYPE)
		{
			MD_BMP_To_Scratch(user_scratch_page_id, Content_table);
			SystemIconStore[SystemIcon[Content_table->Index].Store_Array_Index].location = 2 + user_scratch_page_id;
			SystemIconStore[SystemIcon[Content_table->Index].Store_Array_Index].QuickIndex =i;

		}
		else
		{
			MD_FONT_to_Scratch(user_scratch_page_id, Content_table);
			System_FontStore[System_Font[Content_table->Index].Store_Array_Index].location = 2 + user_scratch_page_id;
			System_FontStore[System_Font[Content_table->Index].Store_Array_Index].QuickIndex = i;
		}
	}

}
#endif

/*********************************************************
TWLL_Osd_Block_fill Using to filling a specific color to the display buffer or scratch buffer.

	pCanvas    		defined where the block fill try to do.

	start_x			Filling area top left point X position
	start_y			Filling area top left point Y Position
	end_X 			Filling area  bottom right X position
	end_Y 			Filling area  bottom right Y position
	color			Filling area color

**********************************************************/
void MD_Rect_Draw(U8 Destination_Index, U8 Destination_Type, RectangleControl_struct *Cntr)
{
	U16 tmp;
	U16 start_X, start_Y, end_X, end_Y,width,heigh;
	U16 tmpl;
	CANVAS* pCanvas;
	SCRATCH* PScratch;
	U8 DispMode;

	start_X = Cntr->XY1.X;
	start_Y = Cntr->XY1.Y;
	end_X   = Cntr->XY2.X;
	end_Y   = Cntr->XY2.Y;
	tmp =  Cntr->Color;

	if(start_X>=end_X)
	{
		width=start_X-end_X;
		start_X=end_X;
	}
	else
		width=end_X-start_X;

	if(start_Y>=end_Y)
	{
		heigh=start_Y-end_Y;
		start_Y=end_Y;
	}
	else
		heigh=end_Y-start_Y;

	if(Destination_Type == SCRATCH_BUFFER)
	{
		PScratch = &(User_Scratch_Page[Destination_Index]);

		if(start_X>PScratch->Scratch_Memory_width) return;

		tmpl = PScratch->Scratch_Memory_width-start_X;
		if(width>tmpl) width=tmpl;

		if(start_Y>PScratch->Scratch_Memory_height) return;

		tmpl = PScratch->Scratch_Memory_height-start_Y;
		if(heigh>tmpl) heigh=tmpl;
		
		start_X=start_X+PScratch->Address1;
		start_Y=start_Y+PScratch->Address2;

		if(User_Scratch_Page[Destination_Index].TargetPlane_Bits_Per_Pixel==8)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
	
	}
	else
	{
		pCanvas = &(User_Canvas[Destination_Index]);

		if(start_X>pCanvas->width) return;

		tmpl = pCanvas->width-start_X;
		if(width>tmpl) width=tmpl;

		if(start_Y>pCanvas->height) return;

		tmpl = pCanvas->height-start_Y;
		if(heigh>tmpl) heigh=tmpl;
		
		start_X=start_X+pCanvas->Mem_X;
		start_Y=start_Y+pCanvas->Mem_Y;

		if(User_Canvas[Destination_Index].Display_Layer==0||User_Canvas[Destination_Index].Display_Layer==1)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
/*
		#ifdef Used_BlockTransfer
		if((BlockTransStatus==1)&&(DispMode==0x10))
			start_X=start_X+800;
		#endif

		#ifdef Update_AvoidBlink
		if((UpdateStatus==1)&&(DispMode==0x10))
			start_X=start_X+800;
		#endif

		#ifdef Support_PagerSlide
		if((PagerSlideStatus==1)&&(DispMode==0x10))
		{
			if(PagerSlideDirection==0x02) //direction is left
			start_X=start_X+800;
			else if(PagerSlideDirection==0x03) //direction is right
			start_X=start_X+0;
			else if(PagerSlideDirection==0x00) //direction is up
			start_Y=start_Y+480;
			else if(PagerSlideDirection==0x01) //direction is down
			start_Y=start_Y+0;
		}
		#endif
*/
		start_Y += 272;
	}

	//Printf("\nstart_X=%d\r\n",start_X);

	OSD_BlockFill(start_X,start_Y,width,heigh,tmp,DispMode);

}

#ifndef DP80390
void MD_Line_Draw(U8 Destination_Index, U8 Destination_Type, LineControl_struct * Cntr)
{
    	Point XY_S, XY_E;
	U16 LineColor;
	U8 DispMode;

	XY_S.x=Cntr->XY1.X;
	XY_S.y=Cntr->XY1.Y;
	XY_E.x=Cntr->XY2.X;
	XY_E.y=Cntr->XY2.Y;
	LineColor=Cntr->Color;
	
	if(Destination_Type == SCRATCH_BUFFER)
	{
		XY_S.x=XY_S.x+User_Scratch_Page[Destination_Index].Address1;			
   		XY_S.y=XY_S.y+User_Scratch_Page[Destination_Index].Address2;
		XY_E.x=XY_E.x+User_Scratch_Page[Destination_Index].Address1;			
   		XY_E.y=XY_E.y+User_Scratch_Page[Destination_Index].Address2;
		
		if(User_Scratch_Page[Destination_Index].TargetPlane_Bits_Per_Pixel==8)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
	}
	else
	{
		XY_S.x=XY_S.x+User_Canvas[Destination_Index].Mem_X;
		XY_S.y=XY_S.y+User_Canvas[Destination_Index].Mem_Y;
		XY_E.x=XY_E.x+User_Canvas[Destination_Index].Mem_X;
		XY_E.y=XY_E.y+User_Canvas[Destination_Index].Mem_Y;

		if(User_Canvas[Destination_Index].Display_Layer==0||User_Canvas[Destination_Index].Display_Layer==1)
			DispMode=0x08; //wino or win1
		else
			DispMode=0x10; //win4
	}	

	OSD_DrawLine(XY_S.x,XY_S.y,XY_E.x,XY_E.y,LineColor,DispMode);
		
}         
#endif
/******************************************************************************
Using to get the width and height of specific font

Parameters
Font_index is a character's Unicode, which indicate which font information to get.
width store the width information
height store the height information
*******************************************************************************/
void MD_Get_FONT_Size(U16 Font_index, U8 *width, U8* height)
{
	unsigned char i;
	U8 Wid,Heig;
	FONTINFO * FontInfo;

	for(i=0;i<MAX_FONT_SET;i++)
	{
		if((System_Font_Index[i].first_character <= Font_index )&& (System_Font_Index[i].last_character >= Font_index)) break;
	}
	
	FontInfo = &System_Font[i];
	Font_index -= System_Font_Index[i].first_character; //here Font_index is number
	Wid = (FontInfo->character_info + Font_index)->character_width;
	Heig = FontInfo->max_character_height;
	/*switch(FontInfo->bits_per_pixel)
	{
		case 1:
			Wid = (Wid+7)>>3<<3;
			break;
		case 2:
			Wid = (Wid+3)>>2<<2;
			break;
		case 4:
			Wid = (Wid+1)>>1<<1;
			break;
	}*/

	*width = Wid;
	*height = Heig;

}

void MD_Get_String_Size(UIControlString_struct *UIString, U16 *width, U16 *height)
{
	unsigned char Font_W, Font_H;

	U16 *str=UIString->Character[OSDLang].Str_Lang;

	*width =0;
	
	while(*str)
	{
		MD_Get_FONT_Size(*str, &Font_W, &Font_H);
		*width += Font_W+UIString->SpaceBetweenCharacter;
		*height = Font_H;
		str++;
	}

	return;
}

void MD_Get_Icon_size(U16 icon_index, U16 *width, U16 *height )
{
	*width  = SystemIcon[icon_index].width;
	*height = SystemIcon[icon_index].height;	
}

